home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / checkbox / arguments.py < prev    next >
Text File  |  2009-11-05  |  4KB  |  96 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Checkbox is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. from inspect import getargspec
  20.  
  21. from checkbox.lib.decorator import merge_function_metadata
  22.  
  23.  
  24. class ArgumentReplacer(object):
  25.     """A decorator helper that filters arguments to be passed to a function.
  26.  
  27.     Create one with the original function and a function to replace
  28.     the arguments, and then call replace_arguments for each call to
  29.     the function.
  30.     """
  31.     def __init__(self, original_function, argument_replacer):
  32.         """
  33.         @param original_function: The function which will be called
  34.             soon. The function must *not* define any * or ** parameters.
  35.         @param argument_replacer: A function which will be called for
  36.             every argument. It will be passed a parameter name and the
  37.             associated argument. It should return the new value.
  38.         """
  39.         self.original_function = original_function
  40.         self.argument_replacer = argument_replacer
  41.  
  42.         spec = getargspec(original_function)
  43.         self.all_arguments = spec[0]
  44.         if getattr(original_function, 'im_self', None) is not None:
  45.             # If it's bound, ignore the bound arguments.
  46.             self.all_arguments = self.all_arguments[1:]
  47.  
  48.     def replace_arguments(self, args, kwargs):
  49.         """Filter some arguments destined to be passed to a function.
  50.  
  51.         @param args: Original positional arguments.
  52.         @param kwargs: Original keyword arguments.
  53.  
  54.         @return: new arguments and kwarguments.
  55.         """
  56.         args = list(args)
  57.         kwargs = kwargs.copy()
  58.  
  59.         for name_index, name in enumerate(self.all_arguments):
  60.             # Ok, we've got the name of the argument. Let's find the value
  61.             # of the argument in our original arguments and replace it
  62.             # whether it's a positional or a keyword argument.
  63.             if name_index < len(args):
  64.                 # Must be a positional argument
  65.                 value = args[name_index]
  66.                 args[name_index] = self.argument_replacer(name, value)
  67.             else:
  68.                 # Must be a keyword argument
  69.                 if name not in kwargs:
  70.                     # Oh, but it wasn't passed in. Ignore it.
  71.                     continue
  72.                 value = kwargs[name]
  73.                 kwargs[name] = self.argument_replacer(name, value)
  74.         return args, kwargs
  75.  
  76.  
  77. def coerce_arguments(**schemas):
  78.     """
  79.     A decorator factory which returns a decorator which coerces arguments.
  80.     """
  81.     def replacer(name, value):
  82.         if name in schemas:
  83.             return schemas[name].coerce(value)
  84.         return value
  85.  
  86.     def decorator(original):
  87.         argument_replacer = ArgumentReplacer(original, replacer)
  88.         def replacement(*args, **kwargs):
  89.             new_args, new_kwargs = argument_replacer.replace_arguments(args,
  90.                                                                        kwargs)
  91.             return original(*new_args, **new_kwargs)
  92.         merge_function_metadata(original, replacement)
  93.         return replacement
  94.  
  95.     return decorator
  96.